home *** CD-ROM | disk | FTP | other *** search
/ The Atari Compendium / The Atari Compendium (Toad Computers) (1994).iso / files / prgtools / mint / mgr / sparcmgr / src.zoo / src / port / line.c < prev    next >
Encoding:
C/C++ Source or Header  |  1989-09-26  |  4.8 KB  |  179 lines

  1. /*                        Copyright (c) 1989 Bellcore
  2.  *                            All Rights Reserved
  3.  *       Permission is granted to copy or use this program, EXCEPT that it
  4.  *       may not be sold for profit, the copyright notice must be reproduced
  5.  *       on copies, and credit should be given to Bellcore where it is due.
  6.  *       BELLCORE MAKES NO WARRANTY AND ACCEPTS NO LIABILITY FOR THIS PROGRAM.
  7.  */
  8. /*    $Header: line.c,v 1.3 89/05/25 07:51:36 sau Locked $
  9.     $Source: /usr/u/sau/mgr/src/dec/RCS/line.c,v $
  10. */
  11. static char    RCSid_[] = "$Source: /usr/u/sau/mgr/src/dec/RCS/line.c,v $$Revision: 1.3 $";
  12.  
  13. #include "bitmap.h"
  14.  
  15. /*  Draw a line  - Bresenham method , portable Bitblt version (S. A. Uhler)
  16.  */
  17.  
  18. bit_line(dest, x0, y0, x1, y1, func)
  19. register BITMAP *dest;                /* destination bitmap */    
  20. int x0, y0, x1, y1;                    /* line coordinates */
  21. int func;                                /* set, clear, or invert */
  22.    {
  23.    register unsigned bit;            /* bit offset in current word */
  24.    register DATA *dst;                /* current word in bitmap */
  25.     register int count;                /* current x position in loop */
  26.     register int err;                    /* accumulated error */
  27.    register int d_incr;                /* words to next scan line */
  28.    register int rincr, rdecr;
  29.    int dx, dy;                            /* # of pixels in x and y */
  30.    int temp;
  31.  
  32.    /* clip here */
  33.  
  34. #ifndef NOCLIP
  35.  
  36. #define TOP    001
  37. #define BOTTOM    002
  38. #define LEFT    004
  39. #define RIGHT    010
  40. #define CROSS(x,y) \
  41.       (x<0 ? LEFT : x>= (dest->wide) ? RIGHT : 0) + \
  42.       (y < 0 ? TOP : y >=  (dest -> high) ? BOTTOM : 0)
  43.  
  44.       {
  45.  
  46.       /* The classic line clipping algorithm */
  47.         /* (I don't remember anymore where I got it from, sorry -sau) */
  48.  
  49.       register int cross0 = CROSS(x0, y0);
  50.       register int cross1 = CROSS(x1, y1);
  51.  
  52.       while (cross0 || cross1) {
  53.           int cross, x, y;
  54.           if (cross0 & cross1)
  55.              return;
  56.           if (cross0 != 0)
  57.              cross = cross0;
  58.           else
  59.              cross = cross1;
  60.           if (cross & (LEFT | RIGHT)) {
  61.              int edge = (cross & LEFT) ? 0 : dest->wide - 1;
  62.              y = y0 + (y1 - y0) * (edge - x0) / (x1 - x0);
  63.              x = edge;
  64.              }
  65.           else if (cross & (TOP | BOTTOM)) {
  66.              int edge = (cross & TOP) ? 0 : dest->high - 1;
  67.              x = x0 + (x1 - x0) * (edge - y0) / (y1 - y0);
  68.              y = edge;
  69.              }
  70.           if (cross == cross0) {
  71.              x0 = x;
  72.              y0 = y;
  73.              cross0 = CROSS(x, y);
  74.              }
  75.           else {
  76.              x1 = x;
  77.              y1 = y;
  78.              cross1 = CROSS(x, y);
  79.              }
  80.          }
  81.       }
  82.  
  83.    /* end of clipping */
  84.  
  85. #endif
  86.  
  87.    x0 += dest->x0;
  88.    y0 += dest->y0;
  89.    x1 += dest->x0;
  90.    y1 += dest->y0;
  91.  
  92.    /* always draw left to right */
  93.  
  94.    if (x1 < x0) {
  95.       temp = x1, x1 = x0, x0 = temp;
  96.       temp = y1, y1 = y0, y0 = temp;
  97.       }
  98.    dx = x1 - x0;
  99.    dy = y1 - y0;
  100.  
  101.    d_incr = BIT_LINE(dest);
  102.    dst = y0 * d_incr + (x0>>LOGBITS) +  (dest->data);
  103.    bit = GETLSB(MSB,(x0&BITS));
  104.  
  105.    if (dy <= 0)
  106.       d_incr = -d_incr, dy = -dy;
  107.  
  108. #ifdef INVERT
  109.     /* invert all raster ops */
  110.  
  111.     func = op_invert[15&func];
  112. #endif
  113.  
  114. #define XMOVE if ((bit=GETLSB(bit,1))==0) {bit = MSB; dst++;}
  115. #define YMOVE dst += d_incr
  116.  
  117. #define STEP(dx,dy,xmove,ymove,op) {        \
  118.     rincr = (dx - dy)<<1;            \
  119.     rdecr = -(dy<<1);                \
  120.     err = dx + rdecr;                \
  121.     for (count = dx; count >= 0; count--) {    \
  122.         op;                        \
  123.         xmove;                        \
  124.         if (err < 0) {                \
  125.             ymove;                \
  126.             err += rincr;                \
  127.             }                    \
  128.         else {                    \
  129.             err += rdecr;                \
  130.             }                    \
  131.         }                     \
  132.     }
  133.  
  134.    if (dx > dy) {            /* gentle slope (this could be made faster) */
  135.       switch (OPCODE(func)) {
  136.           case OPCODE(SRC):
  137.           case OPCODE(SRC | DST):
  138.           case OPCODE(SRC | ~DST):
  139.           case OPCODE(~0):
  140.               STEP(dx, dy, XMOVE, YMOVE, *dst |= bit);                /* set */
  141.              break;
  142.           case OPCODE(~SRC):
  143.           case OPCODE(~(SRC|DST)):
  144.           case OPCODE(DST & ~SRC):
  145.           case OPCODE(0):
  146.               STEP(dx, dy, XMOVE, YMOVE, *dst &= ~bit);            /* clear */
  147.              break;
  148.           case OPCODE(SRC ^ DST):
  149.           case OPCODE(~DST):
  150.           case OPCODE(SRC & ~DST):
  151.           case OPCODE(~(SRC&DST)):
  152.               STEP(dx, dy, XMOVE, YMOVE, *dst ^= bit);                /* invert */
  153.              break;
  154.          }
  155.       }
  156.    else    {            /* steep slope */
  157.       switch (OPCODE(func)) {
  158.           case OPCODE(SRC):
  159.           case OPCODE(SRC | DST):
  160.           case OPCODE(SRC | ~DST):
  161.           case OPCODE(~0):
  162.               STEP(dy, dx, YMOVE, XMOVE, *dst |= bit);                /* set */
  163.              break;
  164.           case OPCODE(~SRC):
  165.           case OPCODE(~(SRC|DST)):
  166.           case OPCODE(DST & ~SRC):
  167.           case OPCODE(0):
  168.               STEP(dy, dx, YMOVE, XMOVE, *dst &= ~bit);            /* clear */
  169.              break;
  170.           case OPCODE(SRC ^ DST):
  171.           case OPCODE(~DST):
  172.           case OPCODE(SRC & ~DST):
  173.           case OPCODE(~(SRC&DST)):
  174.               STEP(dy, dx, YMOVE, XMOVE, *dst ^= bit);                /* invert */
  175.              break;
  176.          }
  177.        }
  178.    }
  179.